﻿using System;
using System.Collections;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using InfoJetSoft.Service.Entity;

namespace InfoJetSoft.Service.Util
{
	
	//在Xslt中调用的xdImage扩展函数。
	//附件，图片都是在getImageUrl中进行解码并缓存到服务器磁盘上的。
	//getFileName，getFileSize是InfoJet Service的自定义函数，用于显示附件的文件名和大小。
	//getFileName，getFileSize在XSNViewFormatControlWorker.formatFileAttachment中添加到Xslt中。
    public class ExtXdImageFunction : IExtensionFunctions
	{
		
		private Form form = null;

		public ExtXdImageFunction( Form frm )
		{
			this.form = frm;
        }

        //CID 0755 //2011.01.14 //Begin
        #region IExtensionFunction Members

        public string Prefix
        {
            get { return this.form.Manifest.NsResolver.GetPrefix(this.NamespaceURI); }
        }

        public string NamespaceURI
        {
            get { return JetConstant.URI_XDIMAGE; }
        }

        public IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] argTypes)
        {
            throw new InfoJetException("Unimplemented Function.", prefix + ":" + name);
        }

        public object InvokeFunction(string prefix, string name, XsltContext xsltContext, object[] args, XPathNavigator docContext)
        {
            throw new InfoJetException("Unimplemented Function.", prefix + ":" + name);
        }

        #endregion
        //CID 0755 //2011.01.14 //End

        //CID 2081 //2014.01.09 //Begin
        public string isListAttachments(System.Object data)
        {
            if (data is XPathNodeIterator)
            {
                XPathNodeIterator nodeIterator = (XPathNodeIterator)data;
                if (nodeIterator.MoveNext())
                {
                    XmlNode currentNode = ((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode();
                    string content = nodeIterator.Current.Value;
                    if (content != null && content.StartsWith(JetConstant.xdListAttachments))
                    {
                        return "1";
                    }
                }
            }
            return "0";
        }
        //CID 2081 //2014.01.09 //End

        //CID 2166 //2014.02.25 //Begin
        public string isListAttachmentsReadonly()
        {
            if (this.form.JetContext.IsListAttachmentsReadonly)
            {
                return "1";
            }
            string isListAttachmentsReadonly = (string)form.ParamTable[ JetConstant.XDOC_PARAM_LIST_ATTACHMENTS_READONLY ];
            if (isListAttachmentsReadonly != null && isListAttachmentsReadonly.Equals(JetConstant.HTML_true))
            {
                return "1";
            }
            return "0";
            
        }
        //CID 2166 //2014.02.25 //End

        //CID 2081 //2014.01.09 //Begin
        public XPathNodeIterator getListAttachmentUrls(System.Object data)
        {
            XmlDocument doc = new XmlDocument();
            XmlElement urlsElement = doc.CreateElement("urls");
            doc.AppendChild(urlsElement);
            if (data is XPathNodeIterator)
            {
                XPathNodeIterator nodeIterator = (XPathNodeIterator)data;
                if (nodeIterator.MoveNext())
                {
                    XmlNode currentNode = ((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode();
                    string content = nodeIterator.Current.Value;
                    //如果有数据
                    if (content != null && content.Length > 0)
                    {
                        if (content.IndexOf(JetConstant.xdListAttachments) == 0)
                        {
                            string[] parts = content.Split(new char[] { '\n' });
                            if (parts.Length > 1)
                            {
                                for (int index = 1; index < parts.Length; index++)
                                {
                                    string part = parts[index].Trim();
                                    if (part.Length > 0)
                                    {
                                        XmlElement urlElement = doc.CreateElement("url");
                                        urlElement.InnerText = part;
                                        urlsElement.AppendChild(urlElement);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            XPathNavigator navi = doc.CreateNavigator();
            return navi.Select("/");
        }
        //CID 2081 //2014.01.09 //End

        //CID 2081 //2014.01.09 //Begin
        public string getAttachmentName(System.Object data)
        {
            if (data is XPathNodeIterator)
            {
                XPathNodeIterator nodeIterator = (XPathNodeIterator)data;
                if (nodeIterator.MoveNext())
                {
                    XmlNode currentNode = ((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode();
                    string content = nodeIterator.Current.Value;
                    int index = content.LastIndexOf("/");
                    if (index >= 0)
                    {
                        string name = content.Substring(index + 1);
                        return name;
                    }
                    else
                    {
                        index = content.LastIndexOf("\\");
                        if (index >= 0)
                        {
                            string name = content.Substring(index + 1);
                            return name;
                        }
                        else
                        {
                            return content;
                        }
                    }
                }
            }
            return null;
        }
        //CID 2081 //2014.01.09 //End

        //CID 2081 //2014.01.09 //Begin
        public string getAttachmentHref(System.Object data)
        {
            if (data is XPathNodeIterator)
            {
                XPathNodeIterator nodeIterator = (XPathNodeIterator)data;
                if (nodeIterator.MoveNext())
                {
                    XmlNode currentNode = ((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode();
                    string content = nodeIterator.Current.Value;
                    return content;
                }
            }
            return null;
        }
        //CID 2081 //2014.01.09 //End

        //CID 2081 //2014.01.09 //Begin
        public string isAttachmentLink(System.Object data)
        {
            if (data is XPathNodeIterator)
            {
                XPathNodeIterator nodeIterator = (XPathNodeIterator)data;
                if (nodeIterator.MoveNext())
                {
                    XmlNode currentNode = ((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode();
                    string content = nodeIterator.Current.Value;
                    if (content.IndexOf("/") >= 0)
                    {
                        return "1";
                    }
                    else
                    {
                        return "0";
                    }
                }
            }
            return null;
        }
        //CID 2081 //2014.01.09 //End

		//获取附件，图片的服务器路径。
        //xdImage:getImageUrl
		public string getImageUrl(System.Object data)
		{
			if (data is XPathNodeIterator)
			{
				XPathNodeIterator nodeIterator = (XPathNodeIterator) data;
				if (nodeIterator.MoveNext())
				{
					XmlNode currentNode = ((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode();
					string content = nodeIterator.Current.Value;
					//如果有数据
					if( content != null && content.Length > 0 )
					{
						string link = getExtendInfo( currentNode, "_link" );
						if( link != null )
						{
							return link;
						}
					} 
				}
			}
			return "";
		}

        //xdImage:getFileName
		public string getFileName(System.Object data)
		{
			if (data is XPathNodeIterator)
			{
				XPathNodeIterator nodeIterator = (XPathNodeIterator) data;
				if (nodeIterator.MoveNext())
				{
					XmlNode currentNode = ((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode();
					string name = getExtendInfo( currentNode, "_name" );
					if( name != null )
					{
						return name;
					}
				}
			}
			return ConfigUtil.SelectFileMessage();
		}

        //xdImage:getFileSize
        public string getFileSize(System.Object data)
        {
            if (data is XPathNodeIterator)
            {
                XPathNodeIterator nodeIterator = (XPathNodeIterator)data;
                if (nodeIterator.MoveNext())
                {
                    XmlNode currentNode = ((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode();
                    string size = getExtendInfo(currentNode, "_size");
                    if (size != null)
                    {
                        size = " " + size;
                        return size;
                    }
                }
            }
            return "";
        }

        //xdImage:existFile
		public string existFile(System.Object data)
		{
			if (data is XPathNodeIterator)
			{
				XPathNodeIterator nodeIterator = (XPathNodeIterator) data;
				if (nodeIterator.MoveNext())
				{
					XmlNode currentNode = ((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode();
					string nodeValue = DOMUtil.getNodeValue( currentNode );
					if( nodeValue == null || nodeValue.Length <= 0 )
					{
						return "0";
					}
					else
					{
						return "1";
					}
				}
			}
			return "0";
		}

		//虽然不再支持XmlNode,但是在一些情况下仍然需要根据Path查找到extendInfo.
		//如<fields><repeating/><file></fields>
		//在这种情况下,repeating的删除,插入等操作,都会造成file无法找到.
		private string getExtendInfo( XmlNode currentNode, string infoPostfix )
		{
			//这个函数解决在一个InlineFile元素同时又有Repeating性质时,删除Repeating导致索引变化无法,找到对应的附件信息的情况.
			string nodeValue = currentNode.InnerText;
			string jetId = DOMUtil.getNodeJetId( currentNode );
            //CID 0761 //2011.01.13 //Begin
            if (!nodeValue.StartsWith(JetConstant.xdInlineFile))
            {
                //CID 0861 //2011.04.11 //isBASE64Field()
                if (Base64TypeUtil.isBase64Node(form, currentNode))
                {
                    XImageDecoder.cacheImage(form, currentNode, nodeValue);
                    //CID 0749 //2011.09.03 //Begin
                    nodeValue = currentNode.InnerText;
                    if (nodeValue.StartsWith(JetConstant.xdInlineFile))
                    {
                        FormUtil.updateFieldValue(form, jetId, nodeValue);
                        if (this.form.CachedImageNodeIdList == null)
                        {
                            this.form.CachedImageNodeIdList = new ArrayList();
                        }
                        if (!this.form.CachedImageNodeIdList.Contains(jetId))
                        {
                            this.form.CachedImageNodeIdList.Add(jetId);
                        }
                    }
                    else
                    {
                        XFileAttachmentDecoder.cacheFile(form, currentNode, nodeValue);
                        nodeValue = currentNode.InnerText;
                        FormUtil.updateFieldValue(form, jetId, nodeValue);
                    }
                    //CID 0749 //2011.09.03 //End
        
                }
            }
            //CID 0761 //2011.01.13 //End
			if( nodeValue.StartsWith( JetConstant.xdInlineFile ) )
			{
				//如果是能够获得xdInlineFile的路径,直接使用路径信息:
				string link = nodeValue.Substring( JetConstant.xdInlineFile.Length );
				if( infoPostfix.Equals( "_link" ) )
				{
					return link;
				}
				else if( infoPostfix.Equals( "_name" ) )
				{
					//CID 0144 //2008.10.20 //Begin
					if( form.JetContext.InlineFileStorage != null )
					{
						string name = form.JetContext.InlineFileStorage.GetName( link );
						return name;
					}
					//CID 0144 //2008.10.20 //End
					else
					{
						string formatedlink = link.Replace( "\\", "/" );
						int lastIndex = formatedlink.LastIndexOf( "/" );
						if( lastIndex >= 0 )
						{
							string name = formatedlink.Substring( lastIndex + 1 );
							return name;
						}
						else
						{
							return link;
						}
					}
				}
				else if( infoPostfix.Equals( "_size" ) )
				{
					//CID 0144 //2008.10.20 //Begin
					if( form.JetContext.InlineFileStorage != null )
					{
						string fileSize = form.JetContext.InlineFileStorage.GetSize( link );
						return fileSize;
					}
					//CID 0144 //2008.10.20 //End
					else
					{
						string diskPath = form.HttpContext.Server.MapPath( link );
						FileInfo fileInfo = new FileInfo( diskPath );
						return fileInfo.Length + "b";
					}
				}
			}
			return null;
		}
    }
}